package com.lizicloud.infrastructure.common.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 反射工具类
 */
public class ReflectionUtils {
    
    /**
     * 获取类的所有字段（包括父类）
     */
    public static List<Field> getAllFields(Class<?> clazz) {
        List<Field> fields = new ArrayList<>();
        Class<?> current = clazz;
        
        while (current != null && current != Object.class) {
            fields.addAll(Arrays.asList(current.getDeclaredFields()));
            current = current.getSuperclass();
        }
        
        return fields;
    }
    
    /**
     * 获取类的指定字段
     */
    public static Field getField(Class<?> clazz, String fieldName) {
        Class<?> current = clazz;
        
        while (current != null && current != Object.class) {
            try {
                return current.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
                current = current.getSuperclass();
            }
        }
        
        return null;
    }
    
    /**
     * 获取字段值
     */
    public static Object getFieldValue(Object obj, String fieldName) {
        if (obj == null || fieldName == null) {
            return null;
        }
        
        try {
            Field field = getField(obj.getClass(), fieldName);
            if (field == null) {
                return null;
            }
            
            field.setAccessible(true);
            return field.get(obj);
        } catch (Exception e) {
            throw new RuntimeException("获取字段值失败: " + fieldName, e);
        }
    }
    
    /**
     * 设置字段值
     */
    public static void setFieldValue(Object obj, String fieldName, Object value) {
        if (obj == null || fieldName == null) {
            return;
        }
        
        try {
            Field field = getField(obj.getClass(), fieldName);
            if (field == null) {
                throw new RuntimeException("字段不存在: " + fieldName);
            }
            
            field.setAccessible(true);
            field.set(obj, value);
        } catch (Exception e) {
            throw new RuntimeException("设置字段值失败: " + fieldName, e);
        }
    }
    
    /**
     * 获取类的所有方法（包括父类）
     */
    public static List<Method> getAllMethods(Class<?> clazz) {
        List<Method> methods = new ArrayList<>();
        Class<?> current = clazz;
        
        while (current != null && current != Object.class) {
            methods.addAll(Arrays.asList(current.getDeclaredMethods()));
            current = current.getSuperclass();
        }
        
        return methods;
    }
    
    /**
     * 获取类的指定方法
     */
    public static Method getMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
        Class<?> current = clazz;
        
        while (current != null && current != Object.class) {
            try {
                return current.getDeclaredMethod(methodName, parameterTypes);
            } catch (NoSuchMethodException e) {
                current = current.getSuperclass();
            }
        }
        
        return null;
    }
    
    /**
     * 调用方法
     */
    public static Object invokeMethod(Object obj, String methodName, Object... args) {
        if (obj == null || methodName == null) {
            return null;
        }
        
        try {
            Class<?>[] parameterTypes = null;
            if (args != null && args.length > 0) {
                parameterTypes = new Class<?>[args.length];
                for (int i = 0; i < args.length; i++) {
                    parameterTypes[i] = args[i] != null ? args[i].getClass() : null;
                }
            }
            
            Method method = getMethod(obj.getClass(), methodName, parameterTypes);
            if (method == null) {
                throw new RuntimeException("方法不存在: " + methodName);
            }
            
            method.setAccessible(true);
            return method.invoke(obj, args);
        } catch (Exception e) {
            throw new RuntimeException("调用方法失败: " + methodName, e);
        }
    }
    
    /**
     * 调用静态方法
     */
    public static Object invokeStaticMethod(Class<?> clazz, String methodName, Object... args) {
        return invokeMethod(null, methodName, args);
    }
    
    /**
     * 创建对象实例
     */
    public static <T> T newInstance(Class<T> clazz) {
        if (clazz == null) {
            return null;
        }
        
        try {
            return clazz.newInstance();
        } catch (Exception e) {
            throw new RuntimeException("创建对象实例失败: " + clazz.getName(), e);
        }
    }
    
    /**
     * 检查字段是否存在
     */
    public static boolean hasField(Class<?> clazz, String fieldName) {
        return getField(clazz, fieldName) != null;
    }
    
    /**
     * 检查方法是否存在
     */
    public static boolean hasMethod(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
        return getMethod(clazz, methodName, parameterTypes) != null;
    }
    
    /**
     * 获取类的简单名称
     */
    public static String getSimpleName(Class<?> clazz) {
        if (clazz == null) {
            return "";
        }
        return clazz.getSimpleName();
    }
    
    /**
     * 获取类的完整名称
     */
    public static String getFullName(Class<?> clazz) {
        if (clazz == null) {
            return "";
        }
        return clazz.getName();
    }
    
    /**
     * 获取对象的类名
     */
    public static String getClassName(Object obj) {
        if (obj == null) {
            return "";
        }
        return obj.getClass().getName();
    }
    
    /**
     * 检查是否为基本类型
     */
    public static boolean isPrimitive(Class<?> clazz) {
        if (clazz == null) {
            return false;
        }
        return clazz.isPrimitive() || 
               clazz == String.class ||
               clazz == Integer.class ||
               clazz == Long.class ||
               clazz == Double.class ||
               clazz == Float.class ||
               clazz == Boolean.class ||
               clazz == Character.class ||
               clazz == Byte.class ||
               clazz == Short.class;
    }
    
    /**
     * 检查是否为静态字段
     */
    public static boolean isStatic(Field field) {
        if (field == null) {
            return false;
        }
        return Modifier.isStatic(field.getModifiers());
    }
    
    /**
     * 检查是否为静态方法
     */
    public static boolean isStatic(Method method) {
        if (method == null) {
            return false;
        }
        return Modifier.isStatic(method.getModifiers());
    }
    
    /**
     * 获取包名
     */
    public static String getPackageName(Class<?> clazz) {
        if (clazz == null) {
            return "";
        }
        
        Package pkg = clazz.getPackage();
        return pkg != null ? pkg.getName() : "";
    }
    
    /**
     * 获取类的所有接口
     */
    public static List<Class<?>> getInterfaces(Class<?> clazz) {
        List<Class<?>> interfaces = new ArrayList<>();
        if (clazz == null) {
            return interfaces;
        }
        
        Class<?> current = clazz;
        while (current != null && current != Object.class) {
            interfaces.addAll(Arrays.asList(current.getInterfaces()));
            current = current.getSuperclass();
        }
        
        return interfaces;
    }
    
    private ReflectionUtils() {
        // 私有构造函数，防止实例化
    }
}